package com.jie.langlangmall.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.jie.langlangmall.common.constant.StatusConstant;
import com.jie.langlangmall.dao.UmsRoleDao;
import com.jie.langlangmall.mapper.UmsRoleMapper;
import com.jie.langlangmall.mapper.UmsRoleMenuRelationMapper;
import com.jie.langlangmall.mapper.UmsRoleResourceRelationMapper;
import com.jie.langlangmall.model.*;
import com.jie.langlangmall.service.UmsAdminCacheService;
import com.jie.langlangmall.service.UmsRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @Author Jie
 * @Date 2024/11/22 11:25
 * @Email 3217998214@qq.com
 */
@Service
@Slf4j
public class UmsRoleServiceImpl implements UmsRoleService {

    @Autowired
    private UmsRoleDao roleDao;
    @Autowired
    private UmsRoleMapper roleMapper;
    @Autowired
    private UmsAdminCacheService adminCacheService;
    @Autowired
    private UmsRoleMenuRelationMapper roleMenuRelationMapper;
    @Autowired
    private UmsRoleResourceRelationMapper roleResourceRelationMapper;

    /**
     * 根据管理员id获取对应的菜单
     *
     * @param adminId
     * @return
     */
    @Override
    public List<UmsMenu> getMenuList(Long adminId) {
        return roleDao.getMenuList(adminId);
    }

    /**
     * 获取所有角色列表
     *
     * @return
     */
    @Override
    public List<UmsRole> list() {
        return roleMapper.selectByExample(new UmsRoleExample());
    }

    /**
     * 根据角色名称分页获取角色列表
     *
     * @param keyword
     * @param pageSize
     * @param pageNum
     * @return
     */
    @Override
    public List<UmsRole> list(String keyword, Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        UmsRoleExample example = new UmsRoleExample();
        if (!StrUtil.isEmpty(keyword)) {
            // select * from ums_role where name like '%keyword%'
            example.createCriteria().andNameLike("%" + keyword + "%");
        }
        return roleMapper.selectByExample(example);
    }

    /**
     * 修改角色
     *
     * @param id
     * @param role
     * @return
     */
    @Override
    public int update(Long id, UmsRole role) {
        role.setId(id);
        roleMapper.updateByPrimaryKeySelective(role);
        // 角色更新之后，更新和这个角色相关的所有缓存
        adminCacheService.delResourceListByRoleIds(List.of(id));
        return StatusConstant.SUCCESS;
    }

    /**
     * 添加新角色
     *
     * @param role
     * @return
     */
    @Override
    public int create(UmsRole role) {
        role.setCreateTime(new Date());
        role.setAdminCount(0);
        role.setSort(0);
        return roleMapper.insert(role);
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Override
    public int delete(List<Long> ids) {
        UmsRoleExample example = new UmsRoleExample();
        example.createCriteria().andIdIn(ids);
        // delete from ums_role where id in (ids)
        int count = roleMapper.deleteByExample(example);
        // TODO: 删除角色关联的用户表怎么办？
        // 删除缓存
        adminCacheService.delResourceListByRoleIds(ids);
        return count;
    }

    @Override
    public List<UmsMenu> listMenu(Long roleId) {
        return roleDao.getMenuListByRoleId(roleId);
    }

    /**
     * 给指定角色分配菜单
     *
     * @param roleId
     * @param menuIds
     * @return
     */
    @Override
    @Transactional
    public int allocMenu(Long roleId, List<Long> menuIds) {
        // 1. 先删除原来的关系
        UmsRoleMenuRelationExample example = new UmsRoleMenuRelationExample();
        example.createCriteria().andRoleIdEqualTo(roleId);
        roleMenuRelationMapper.deleteByExample(example);
        // 2. 批量插入新的菜单和角色的关系
        if (CollectionUtil.isNotEmpty(menuIds)) {
            for (Long menuId : menuIds) {
                UmsRoleMenuRelation relation = new UmsRoleMenuRelation();
                relation.setRoleId(roleId);
                relation.setMenuId(menuId);
                roleMenuRelationMapper.insert(relation);
            }
        }
        // 更改之后需要删除缓存
        adminCacheService.delResourceListByRoleIds(List.of(roleId));
        return StatusConstant.SUCCESS;
    }

    /**
     * 获取角色相关资源
     *
     * @param roleId
     * @return
     */
    @Override
    public List<UmsResource> listResource(Long roleId) {
        return roleDao.getResourceListByRoleId(roleId);
    }

    @Override
    public int allocResource(Long roleId, List<Long> resourceIds) {
        // 1. 先删除原来的资源和角色关系
        UmsRoleResourceRelationExample example = new UmsRoleResourceRelationExample();
        // delete from ums_role_resource_relation where role_id = roleId
        example.createCriteria().andRoleIdEqualTo(roleId);
        roleResourceRelationMapper.deleteByExample(example);
        // 2. 批量插入新的关系
        if (!CollectionUtil.isEmpty(resourceIds)) {
            for (Long resourceId : resourceIds) {
                UmsRoleResourceRelation relation = new UmsRoleResourceRelation();
                relation.setRoleId(roleId);
                relation.setResourceId(resourceId);
                roleResourceRelationMapper.insert(relation);
            }
        }
        // 3. 更新缓存
        adminCacheService.delResourceListByRole(roleId);
        return StatusConstant.SUCCESS;
    }


}
